﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace TestesFixacao.Dominio.Modelos
{
    public class Questao
    {
        public Questao()
        {
        }

        public Questao(int n, int qtdAlternativas, Materia m)
        {
            Numero = n;
            Alternativas = new List<Alternativa>(qtdAlternativas);
        }

        public int Numero { get; set; }

        public int Bimestre { get; set; }

        public string Enunciado { get; set; }

        public Materia Materia { get; set; }

        public List<Alternativa> Alternativas = new List<Alternativa>();

        public void AdicionaAlternativa(Alternativa alternativa)
        {
            int qtdAlternativasCorretas = ObtemQuantidadeAlternativaCorreta();

            if (qtdAlternativasCorretas > 0 && alternativa.Correta)
            {
                throw new ApplicationException("Não pode cadastrar duas alternativas corretas para a questão: " + Numero);
            }
            else if (qtdAlternativasCorretas == 0 && EhUltimaPosicao() && alternativa.Correta == false)
            {
                throw new ApplicationException("Ao menos uma alternativa correta deverá ser informado para a questão: " + Numero);
            }
            else
            {
                Alternativas.Add(alternativa);
            }
        }

        public Alternativa ObtemAlternativaCorreta()
        {
            return Alternativas.Where(x => x.Correta).First();
        }

        private bool EhUltimaPosicao()
        {
            return ObtemQuantidadeAlternativaCadastrada() == Alternativas.Count - 1;
        }

        private int ObtemQuantidadeAlternativaCadastrada()
        {
            return Alternativas.Count();
        }

        private int ObtemQuantidadeAlternativaCorreta()
        {
            return Alternativas.Count(x => x.Correta);
        }

        public override string ToString()
        {
            return string.Format("Número: {0}, {1}", Numero, Enunciado);
        }

        public void EditaAlternativa(Alternativa alternativa)
        {
            var alternativaAtualizada = Alternativas.Single(x => x.Letra == alternativa.Letra);

            alternativaAtualizada.Letra = alternativa.Letra;
            alternativaAtualizada.Correta = alternativa.Correta;
            alternativaAtualizada.Resposta = alternativa.Resposta;
        }

        public void RemoveAlternativa(Alternativa alternativaSelecionada)
        {
            Alternativas.Remove(alternativaSelecionada);
        }

        public void Valida()
        {
            if (Materia == null)
                throw new Exception("Materia obrigatoria.");
            if (Enunciado.Length == 0)
                throw new Exception("Enunciado obrigatório.");
            if (ObtemQuantidadeAlternativaCadastrada() < 4)
                throw new Exception("Cadastre no minimo 4 alternativas.");

            int numeroDeCorretas = 0;
            if (Alternativas != null)
            {
                foreach (Alternativa item in Alternativas)
                {
                    if (item.Correta)
                        numeroDeCorretas++;

                    if (item.Resposta == null || item.Resposta.Length == 0)
                        throw new Exception("Alternativa não possui resposta");
                }
            }
            else
                throw new Exception("Cadastre no minimo 4 alternativas.");

            if (numeroDeCorretas == 0)
                throw new Exception("A questão deve ter uma alternativa correta.");

            if (numeroDeCorretas > 1)
                throw new Exception("A questão deve ter apenas uma alternativa correta.");
        }
    }
}